package com.supermap.wzhy.module.fr.service;

import com.supermap.wzhy.data.ConfigHelper;
import com.supermap.wzhy.data.SysConstant;
import com.supermap.wzhy.entity.*;
import com.supermap.wzhy.module.data.dao.MicroIdenmetaDao;
import com.supermap.wzhy.module.data.dao.MicroTablemetaDao;
import com.supermap.wzhy.module.fr.dao.FrDao;
import com.supermap.wzhy.module.fr.dao.WjgDao;
import com.supermap.wzhy.module.user.dao.UserTaskDao;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 文件柜导出线程
 * Created by W.Qiong on 16-12-28.
 */
public class FrWjgExpRunnable  implements  Runnable{
    private final  static String BASE_TABLE ="YZYM_E_BASEINFO";
    private final  static String UNIQ_FIELD ="ETPSID" ; //唯一标识字段
    //子报表
    private final  static String[] SUB_TABLES =new String[]{"YZYM_E_BASEINFO","YZYM_E_LEREP","YZYM_E_FINANCE","YZYM_E_INV"
            ,"","YZYM_E_SUB","YZYM_E_ALT","YZYM_E_CANCEL"};

    //子报表节点
    private final  static String[] SUB_TABLES_NODES =new String[]{"RECORD","LEREP","INFOFINANCE","INVESTORLIST-INVESTORDOCUMENT"
            ,"","PARENTENTDOCUMENT","INFOALTS-INFOALT","INFOCANCLE"};

    //企业注销信息表
    private final String cancelInfoTable = "YZYM_E_CANCEL";

    //企业注销-注销
    private final String Cancel_zx = "2";
    //企业注销-吊销
    private final String Cancel_dx = "4";


    //变更信息表
    private final String changeInfoTable = "YZYM_E_ALT";
    //变更信息-变更
    private final String Alt_bg = "1";
    //变更信息-修改
    private final String Alt_xg = "3";


    //企业隶属信息表
    private final String subTable = "YZYM_E_SUB";

    FrDao frDao ;
    MicroTablemetaDao microTablemetaDao ;
    MicroIdenmetaDao microIdenmetaDao ;
    UserTaskDao userTaskDao ;

    WjgDao wjgDao;

    Date startTime ;
    Date endTime ;
    int maxSize = 0 ;
    String userName;

    private static  boolean isRunning = false ;

    /**
     * 设置dao
     * @param frDao
     * @param microTablemetaDao
     * @param microIdenmetaDao
     * @param userTaskDao
     */
    public void setDao(FrDao frDao,MicroTablemetaDao microTablemetaDao ,
                       MicroIdenmetaDao microIdenmetaDao ,
                       UserTaskDao userTaskDao,WjgDao wjgDao){
        this.frDao = frDao ;
        this.microIdenmetaDao = microIdenmetaDao ;
        this.microTablemetaDao = microTablemetaDao ;
        this.userTaskDao = userTaskDao ;
        this.wjgDao = wjgDao;
    }

    /**
     * 设置用户名
     * @param request
     * @return
     */
    public String setUserName(HttpServletRequest request){
        if(request != null){
            TUsers users = (TUsers)request.getSession().getAttribute(SysConstant.CURRENT_USER);
            if(users != null){
                this.userName = users.getUserName();
            }else{
                this.userName = "admin";
            }
        }else {
            this.userName = "定时任务";
        }
        return this.userName;
    }


    public  void setMaxSize(int maxSize){
        this.maxSize = maxSize ;
    }

    /**
     * 设置提取数据时间
     * @param startTime
     * @param endTime
     */
    public void setTime(Date startTime,Date endTime){
        this.startTime = startTime ;
        this.endTime = endTime ;
    }

    public boolean checkIsRun(){
        return isRunning ;
    }

    @Override
    public void run() {
        isRunning = true ;
        start();
        isRunning = false ;
    }


    /**
     * 检查是否有文件柜导出任务
     * @return
     */
    private  boolean checkWjgTaskRun(){
        return  userTaskDao.findRunningTask("wjg").size()>0; //后面再讲wjg写成常量

    } ;
    /**
     * 生成文件柜数据入口
     */
    public void start(){
        // 记录条数
        int ao = 0;
        //添加任务
        TUsertask usertask = null ;
        int xml_num = 0;
        try {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            String sql ="select * from "+BASE_TABLE;

            int wjgSum = Integer.valueOf(ConfigHelper.get("wjgsum"));
            System.out.println("文件柜包数 "+wjgSum);

            String [] params = new String[2];
            String startTimeStr = "";
            String endTimeStr ="";
            int i =0 ;
            startTimeStr = startTime==null? "2000-01-01 00:00:00":formatter.format(startTime);
            SimpleDateFormat sdft = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            startTime = startTime==null?sdft.parse("2000-01-01 00:00:00"):startTime;
            endTimeStr = formatter.format(endTime==null?new Date():endTime);
            endTime = endTime==null?new Date():endTime;

            params[0] = startTimeStr ;
            params[1] = endTimeStr ;

            sql = " where  to_char(S_EXT_TIMESTAMP,'%Y-%m-%d') >= ? " +
                    "and  to_char(S_EXT_TIMESTAMP,'%Y-%m-%d') <= ? ";

            System.out.println("params 1 : "+params[0]+" params 2 : "+params[1]);

            //找到单位记录总数
            Integer count = frDao.getIntegerUniq("select count(*) from "+BASE_TABLE+ sql,params) ;

            System.out.println("select count(*) from "+BASE_TABLE+ sql);

            if(count == 0){
                return;
            }
            count = maxSize>0&&maxSize<count?maxSize:count ;

            //添加任务
            usertask = addTask(count,"wjg");
            //userTaskDao.save(usertask);
            System.out.println("导出总数: "+count);

            //测试代码开始
//           count = count<500?count:500 ; //只取500条进行测试
            //测试代码结束
            //计算总xml个数

                /**
                 * 分支机构预处理
                 */
                updateSUBLS();
                //分支机构子节点名称
                String str = "CHILDENTLIST-CHILDENT";
                //设置CHILDENT 分支机构TMicroIdenmeta 指标对象
                List<TMicroIdenmeta> list = setIdenmeta();
                //分支机构判断处理条件
                String child_sql_sub = "select * from yzym_e_sub where entname = ?";
                String col = ConfigHelper.get("CHILDENTLIST");
                //分支机构节点值
                String child_sql_base2 = "select etpsid,"+col+" from "+sub_ls +" where entname = ?";


                int perSize = 1000 ; //每次取出1千条
                perSize = count<perSize?count:perSize ;
                int num = count/perSize+(count%perSize==0?0:1);
                Map<String ,List<TMicroIdenmeta>> idenMap = new HashMap<>() ;//指标元数据
                //读取全部报表元数据 第一个为基本信息表
                for(String t:SUB_TABLES){
                    List<TMicroTablemeta>  tablemetaList  = microTablemetaDao.findByTableName(t);
                    if(tablemetaList.size() ==0){
                        continue;
                    }
                    TMicroTablemeta tablemeta  = tablemetaList.get(0) ;
                    idenMap.put(t,microIdenmetaDao.findByWJGIden(tablemeta.getMitmid())) ;
                }
                int xmlNum = 1 ;  //xml数量

                //取一定数目数据
                for(i =1 ; i< num+1 ;i++ ){
                    int perCount =0;//每个xml的记录数
                    int start = (i-1)*perSize ;
                    int end = i*perSize ;
                    boolean sub_child_boo = false;

                    List<Object[]> dataM  = frDao.query("select skip " + start + " first " + perSize + " cast(ETPSID as varchar(50))  ID," + getQueryFields(idenMap.get(BASE_TABLE)) +
                                ",cast(S_EXT_TIMESTAMP as varchar(50))  S_EXT_TIMESTAMP from " + BASE_TABLE + sql + "order by S_EXT_TIMESTAMP" , params) ;

                    //List<Object[]> dataM = frDao.query(list_map) ;

                    //System.out.println(getQueryFields(idenMap.get(BASE_TABLE)));
    //              Document document = DocumentHelper.createDocument();
                    Element data = DocumentHelper.createElement("Data");
                    boolean  needExp = false ;
                    if(dataM==null){  continue; }  //空值判断
                    //一次性获取全部报表数据
                    Map<String ,Map<String,List<Object[]>>>  subTableDataMap = new HashMap<>() ;

                    //假设每次最多只取1000条
                    StringBuilder b = new StringBuilder();
                    //StringBuilder type = new StringBuilder();
                   // String S_EXT_TIMESTAMP = "";
                    for(int d= 0; d<dataM.size() ;d++){
                        String id =  dataM.get(d)[0].toString() ;//单位唯一标识
                        //String t = ""; //信息操作类型
                       /* if(dataM.get(d)[1] != null){
                           // t = dataM.get(d)[1].toString();
                        }*/
                        b.append("'"+id+"'") ;
                        //type.append("'"+t+"'");
                        if(d<dataM.size()-1){
                            b.append(",") ;
                            //type.append(",");
                        }
                    }
                    if(dataM.size()>0){
                        //查询子报表数据  关联查询太慢
                        for(int j=1 ; j< SUB_TABLES.length;j++){
                            if(SUB_TABLES[j]==null||SUB_TABLES[j].equals("")){ continue; }
                            Object[] params1 =new Object[]{params[0],params[1]} ;
                            //跟企业基础信息表关联

                            String subSql = "select  cast(ETPSID as varchar(50))  id," + getQueryFields(idenMap.get(SUB_TABLES[j])) +
                                    " from "+SUB_TABLES[j]+" t   "+sql +" and ETPSID in("+b.toString()+")";

                            //System.out.println(subSql);

                            //System.out.println(SUB_TABLES[j]+" : "+getQueryFields(idenMap.get(SUB_TABLES[j])));
                            List<Object[]> dataList = frDao.query(subSql, params1);


                            if (dataList==null) {
                                System.out.println("错误sql:"+"select  cast(ETPSID as varchar(50))  id," + getQueryFields(idenMap.get(SUB_TABLES[j])) +
                                        " from "+SUB_TABLES[j]+
                                        " t   "+sql );
                                continue;
                            }
                            System.out.println(SUB_TABLES[j]+" 表 dataList size "+dataList.size());

                            /**
                             * 处理企业注销信息
                             */
                            /*
                            //当前企业基本信息是否包含企业注销信息状态
                            boolean cancelInfo = true;
                            if(SUB_TABLES[j].equals(cancelInfoTable)){
                                if(listToMapByEtpsid(dataList).size() == 0){
                                    cancelInfo = false;
                                }
                            }

                            // 未找到企业基本信息的注销企业再生成文件
                            if(cancelInfo){
                                subTableDataMap.put(SUB_TABLES[j],listToMapByEtpsid(dataList)) ;
                            }else{
                                createCancelInfo(count);
                            }*/
                            subTableDataMap.put(SUB_TABLES[j],listToMapByEtpsid(dataList)) ;

                        }
                    }

                    //逐条遍历数据
                    for(int d= 0; d<dataM.size() ;d++){
                        sub_child_boo = false;
                        int record_index = (i-1)*perSize+(d+1);

                        //每个xml包record节点从1开始计数,循环
                        if(record_index > wjgSum){
                            record_index = record_index - (int)Math.ceil(record_index/wjgSum)*wjgSum;
                            if(record_index == 0){
                                record_index = wjgSum;
                            }
                        }
                        //System.out.println(record_index);
                        Element record = createRecord(record_index,dataM.get(d),idenMap.get(BASE_TABLE));

                        String id =  dataM.get(d)[0].toString() ;//单位唯一标识

                      /*  String uniscidstr =  dataM.get(d)[2].toString() ;//社会信用代码
                        String regnostr =  dataM.get(d)[3].toString() ;//社会信用代码
                        */
                        String entnamestr =  dataM.get(d)[4].toString() ;//详细名称

                        //String S_EXT_TIMESTAMP1 = dataM.get(d)[22].toString() ;//数据提取时间
                        //String types = "";
                       /* if(dataM.get(d)[1] != null){
                            //types = dataM.get(d)[1].toString(); //信息操作类型
                        }*/

                        //遍历报表取出子节点数据
                        perCount++ ;
                        needExp = true ;

                        for(int j=1 ; j< SUB_TABLES.length;j++){
                            if(SUB_TABLES[j]==null||SUB_TABLES[j].equals("")){ continue; }
                            if(!subTableDataMap.containsKey(SUB_TABLES[j])){ continue;}
                            List<Object[]> dataList = new ArrayList<>();

                            dataList =  subTableDataMap.get(SUB_TABLES[j]).get(id);
                           /* if(types != ""){
                                //变更信息处理
                                if(SUB_TABLES[j].equals(changeInfoTable)){
                                    if(types.equals(Alt_bg)){
                                        dataList =  subTableDataMap.get(SUB_TABLES[j]).get(id);
                                    }else if(types.equals(Alt_xg)){
                                        dataList =  subTableDataMap.get(SUB_TABLES[j]).get(id);
                                    }else {
                                        dataList =  subTableDataMap.get(SUB_TABLES[j]).get("");
                                    }
                                }
                                //注销信息处理
                                if(SUB_TABLES[j].equals(cancelInfoTable)){
                                    if(types.equals(Cancel_zx)){
                                        dataList =  subTableDataMap.get(SUB_TABLES[j]).get(id);
                                    }else if(types.equals(Cancel_dx)){
                                        dataList =  subTableDataMap.get(SUB_TABLES[j]).get(id);
                                    }else {
                                        dataList =  subTableDataMap.get(SUB_TABLES[j]).get("");
                                    }
                                }
                            }else{
                                System.out.println("信息操作类型为空!");
                            }*/

                            if(dataList == null||dataList.size() ==0){ continue; }

                            Element subTNode = createSubNode(SUB_TABLES_NODES[j],dataList,idenMap.get(SUB_TABLES[j])) ;
                            record.add(subTNode);


                            //同一子节点并列情况
                            if(SUB_TABLES[j].equals(subTable)){
                                //String child_sql_sub = "select * from yzym_e_sub where entname = ? and regno = ? or uniscid = ?";
                                //String child_sql_sub = "select * from yzym_e_sub where entname = ?";
                                List li = frDao.query(child_sql_sub,entnamestr);
                                if(li != null){
                                    if(li.size() > 0){
                                        sub_child_boo = true;
                                    }
                                }
                                //sub_child_boo = sub(id);
                                //判断是否存在分支机构节点的情况
                                if(sub_child_boo){
                                    Map<String,List<TMicroIdenmeta>> map = new HashMap();
                                    map.put(subTable,list);
                                    List sub_d = frDao.query(child_sql_base2,entnamestr);
                                    Element subTNode_child = createSubNode(str,sub_d,map.get(SUB_TABLES[j]));
                                    record.add(subTNode_child);
                                    System.out.println("第 "+ao+" 条数据有分支机构信息!");
                                    //sub_child_boo = false;
                                }
                            }
                        }
                        /** 必须需要法人信息 **/
                        createLerepInfo(record);

                       //含变更信息的不再导出注销信息
                        record = removeDocument(record,"INFOCANCLE",Alt_bg);

                        //含设立信息的不再导出变更信息
                        //record = removeDocument(record,"INFOALTS","0");

                        ao++;
                        data.add(record);

                        //xmlNum = getXmlNum(xmlNum);//每天零点置零

                        //每wjgSum条输出文件
                        if((d+1)%wjgSum == 0){
                            expOneXmlFile(xmlNum++,perCount,data,endTimeStr,sub_child_boo);
                            needExp =false ;
                            perCount =0 ;
                            data = null ;
                            data = DocumentHelper.createElement("Data");
                            //更新进度
                            updateTask((i-1)*perSize+(d+1),usertask) ;
                        }
                    }
                    System.out.println("当前已导出 " + ao + " 数据!");

                    //剩余部分再导出
                    if(needExp){
                        //System.out.println("当前已导出 "+ao+" 数据!");
                        expOneXmlFile(xmlNum++,perCount,data,endTimeStr,sub_child_boo);
                        xml_num = xmlNum;
                        needExp =false ;
                        perCount = 0;
                        //更新进度
                        updateTask(i*perSize,usertask) ;
                    }
                }
                //更新进度

            usertask.setFinished(1);
            usertask.setEndtime(new Date());
            updateTask(count, usertask) ;

            addLog(userName,count,startTime,endTime);
            System.out.println("添加文件柜日志成功");
        }   catch (Exception e){
            //异常时删除正在执行的任务
            if(usertask !=null){
                userTaskDao.delete(usertask);
            }
            e.printStackTrace();
        }finally {
            System.out.println("输出企业数据条数 : "+ao);
            //最后导出注销信息
            //createCancelInfo(ao);
            //后续法人库删除数据导出xml
            //构造方法传参
            FrWjgDelDataExpService frWjgDelDataExpService = new FrWjgDelDataExpService(frDao,microTablemetaDao,microIdenmetaDao,xml_num);
            frWjgDelDataExpService.run();
        }
    }

    //零点重置
    private int getXmlNum(int xmlNum){
        Calendar calendar = Calendar.getInstance();
        int hh = calendar.get(Calendar.HOUR_OF_DAY);
        int min = calendar.get(Calendar.MINUTE);
        //零点重置文件名
        if(hh == 0 && min == 0){
            xmlNum = 1;
        }
        return xmlNum;
    }



    /**
     * 节点文本乱码转换
     * @param txt
     * @return
     */
    private String speacial(String txt){
        String res = "";
        for(int i = 0; i < txt.length(); ++i){
            char ch = txt.charAt(i);
            if( Character.isDefined(ch) && ch!= '&' && ch != '<' && ch != '>'
                    //转换字符是否需要符合高低代理项代码单元?
                    && !Character.isHighSurrogate(ch) && !Character.isISOControl(ch) &&
                    !Character.isLowSurrogate(ch)
                    ){
                res = res + ch;
            }else{
                ch = ' ';
                res += ch;
            }
        }
        return res;
    }


    /**
     * 根据信息操作类型去除XML文档的某个节点
     * @param record 文档根节点
     * @param doc 要去除的子节点
     * @param type 信息操作类型
     * @return
     */
    private Element removeDocument(Element record,String doc,String type){
        List<Element> li = record.selectNodes("INFOACTIONTYPE");
        List<Element> cancel = record.selectNodes(doc);
        //System.out.println(li);
        if(li.size() > 0){
           String text = li.get(0).getText();
           //System.out.println(text);
           if(type.equals(text)){
                if(cancel.size() > 0){
                    record.remove(cancel.get(0));
                }
           }
        }
        return record;
    }

    /**
     * 创建单位数据基本信息节点
     * @param index
     * @param data
     * @param idenmetas
     * @return
     */
    private  Element createRecord(int index ,Object[] data,List<TMicroIdenmeta> idenmetas){

        Element record = DocumentHelper.createElement("Record") ;
        record.addAttribute("index",(index)+"") ;
        int len = idenmetas.size();
        for(int i =0 ; i< len ;i++){
            int type = idenmetas.get(i).getIdenType() ;
            String value = "";
            //格式化日期类型
            if(type == 3){
                try {
                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //yyyy-MM-dd HH:mm:ss

                    if(data[i+1] != null){
                        String de = data[i+1].toString();

                        if(de.contains(".")){
                            de = de.substring(0, de.indexOf("."));
                        }
                        value = formatter.format(formatter.parse(de)) ;
                    }else {
                        value = "";
                    }

                }   catch (Exception e) {
                    System.out.println("日期类型转换出错："+data[i+1]);
                    value ="";
                }
            }else{
                value = data[i+1]!=null?data[i+1].toString():"" ;

                value = speacial(value);

            }
            // 判断文件柜字段是否有别名
            if(idenmetas.get(i).getWjgName() == null){
                record.addElement(idenmetas.get(i).getIdenCode().toUpperCase()).addText(value) ;
            }else{
                record.addElement(idenmetas.get(i).getWjgName().toUpperCase()).addText(value) ;
            }

        }

        return  record ;
    }

    //创建法人信息节点
    private Element createLerepInfo(Element record){

        List<Element> list = record.elements();
        boolean boo = false;
        for(Element ele:list){
            if("LEREP".equals(ele.getName())){
                boo = true;
            }
        }

        if(boo == false){
            Element unisid = record.element("UNISCID");
            String id = unisid.getText();
            Element lerep = DocumentHelper.createElement("LEREP");
            Element lerep_child = DocumentHelper.createElement("LEREP");
            lerep_child.addText(insertLerepText(id));
            lerep.add(lerep_child);

            record.add(lerep);
        }
        return  record;
    }

    private String insertLerepText(String unisid){
        String sql = "select lerep from "+BASE_TABLE+" where UNISCID = ?";
        List list = frDao.query(sql,unisid);
        if(list.size() > 0){
            return list.get(0)==null?"":list.get(0).toString();
        }else{
            return "";
        }

    }


    /**
     * 导出xml文件
     * @param data
     * @return
     */
    private boolean expOneXmlFile(int xmlNum ,int perCount,Element data,String date,boolean coo){

        //SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String number = String.format("%06d", xmlNum);

        String endTime = date.replaceAll("-","");

        String dataPackNum =  "130000" +endTime+number ;   //数据包编号
        //根节点
        Element root = DocumentHelper.createElement("Package");

        Element head = createHead(dataPackNum,perCount) ;//数据头部描述信息
        root.add(head);
        root.add(data);
        //输出文件
        createXmlFile(xmlNum,root,endTime,coo);
        return true ;
    }
    /**
     * 获取子报表的节点
     * @param nodeName
     * @param dataList
     * @param idenmetas
     * @return
     */
    private  Element createSubNode(String nodeName ,List<Object[]>dataList,List<TMicroIdenmeta> idenmetas){
        String[] nodes = nodeName.split("-") ;//多个则要考虑多个子节点
        Element rootNode = DocumentHelper.createElement(nodes[0]) ;
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd");
        int len = idenmetas.size();
        for(Object[] data:dataList){
            Element subNode = nodes.length>1?DocumentHelper.createElement(nodes[1]):null ;
            for(int i =0 ; i< len ;i++){
                int type = idenmetas.get(i).getIdenType() ;
                //int dsize = dataList.size() ;
                String value = "";
                //格式化日期类型
                if(type == 3){
                    try {
                        if(data[i+1] != null){
                            String de = data[i+1].toString();
                            if(de.contains(".")){
                                de = de.substring(0, de.indexOf("."));
                                value = formatter.format(formatter.parse(de)) ;
                            }else{
                                value = formatter2.format(formatter2.parse(de)) ;
                            }
                        }else {
                            value = "";
                        }

                       // value = formatter.format(data[i+1]) ;
                    }   catch (Exception e) {
//                   System.out.println("日期类型转换出错："+data[i+1]);
                        value ="";
                    }
                }else{
                    value = data[i+1]!=null?data[i+1].toString():"" ;

                    value = speacial(value);
                }
                if(subNode == null){
                    if(idenmetas.get(i).getWjgName() != null){
                        rootNode.addElement(idenmetas.get(i).getWjgName().toUpperCase()).addText(value) ;
                    }else{
                        rootNode.addElement(idenmetas.get(i).getIdenCode().toUpperCase()).addText(value) ;
                    }
                }else{
                    if(idenmetas.get(i).getWjgName() != null){
                        subNode.addElement(idenmetas.get(i).getWjgName().toUpperCase()).addText(value) ;
                    }else{
                        subNode.addElement(idenmetas.get(i).getIdenCode().toUpperCase()).addText(value) ;
                    }
                }
            }
            if(subNode != null){
                rootNode.add(subNode) ;
            }
            //createLerepInfo(rootNode);
        }
        return  rootNode ;
    }

    /**
     * 输出xml文件到指定目录
     * @param root
     * @return
     */
    private  boolean createXmlFile(int xmlnum , Element root,String date,boolean coo){
        //设置文件编码
        OutputFormat xmlFormat = new OutputFormat();
        xmlFormat.setEncoding("UTF-8");

        // 设置换行
        xmlFormat.setNewlines(true);
        // 生成缩进
        xmlFormat.setIndent(true);
        xmlFormat.setNewLineAfterDeclaration(false);
        // 使用4个空格进行缩进, 可以兼容文本编辑器
        xmlFormat.setIndent("    ");
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
//        第1到6位为省级行政区划代码；
//        第7到14位为数据交换的日期，表示方法为：YYYYMMDD；
//        第15到20位为顺序号，每天零点置零，以000001为始。
//        举例：WZHY_GSXX_42000020161025000001.xml
        String number = String.format("%06d", xmlnum);
        //文件名包含的日期不能含有'-'
        //date = date.replaceAll("-", "");
        String base =  ConfigHelper.get("wjgpath")+"/"+date +"/"+"tjdata"+"/"+"jbxx"+"/";
        String fileName = "WZHY_GSXX_130000"+ date +number +".xml";
        if(coo){
            System.out.println(fileName);
        }

        String path = base+fileName ;
        File f = new File(base) ;
        if(!f.exists()){ f.mkdirs() ;}
        if(new File(path).exists()){ new File(path).delete() ; }
        try {
            Document document = DocumentHelper.createDocument();
            document.add(root);
            document.setXMLEncoding("UTF-8");

            //创建写文件方法
            FileOutputStream fos = new FileOutputStream(path);
            XMLWriter xmlWriter = new XMLWriter(fos,xmlFormat);

            //写入文件
            xmlWriter.write(document);
            //关闭
            xmlWriter.close();
            System.out.println();
            return  true ;
        }   catch (Exception e){
            e.printStackTrace();
        }
        return  false ;

    }

    /**
     * 构造表头
     * @return
     */
    private Element createHead(String dataPackNum,int perCount){
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddhhmmss");
        Element root = DocumentHelper.createElement("PackageHead") ;
        root.addElement("SJBBH").addText(dataPackNum);   // 数据包编号
        root.addElement("SJBLX").addText("GSXX") ;  //数据包类型
        root.addElement("DWDM").addText("130000") ;    //单位代码
        root.addElement("DWMC").addText("河北省工商行政管理局") ;    //单位名称
        root.addElement("JLS").addText(perCount+"") ;     //记录数
        root.addElement("INFODATE").addText(formatter.format(new Date())) ;  //数据包生成时间，格式为yyyyMMddhhmmss
        System.out.println();
        return  root ;
    }

    /**
     * 获取查询指标字符串
     * @param idenmetas
     * @return
     */
    private String  getQueryFields(List<TMicroIdenmeta> idenmetas){
        StringBuilder b = new StringBuilder() ;
        int index =0 ;
        int size = idenmetas.size() ;
        for(TMicroIdenmeta i:idenmetas){
            //informix char类型转换
            if(i.getIdenType() == 1&&i.getIdenLength()<=255){
                b.append("cast("+i.getIdenCode().toUpperCase()+ " as varchar(255)) "+i.getIdenCode().toUpperCase());
            }else if(i.getIdenType() == 1&&i.getIdenLength()==3000){
                //lvarchar : informix独有的长字符类型
                b.append("cast("+i.getIdenCode().toUpperCase()+ " as lvarchar(3000)) "+i.getIdenCode().toUpperCase());
            }
            else{
                b.append(i.getIdenCode().toUpperCase());
            }

            if(index <size-1){
                b.append(",");
            }
            index++ ;
            System.out.println();
        }
        return b.toString() ;
    }


    /**
     * 将datalist转换成map对象
     * @param datalist
     * @return
     */
    private Map<String , List<Object[]>>  listToMapByEtpsid(List<Object[]> datalist){

        Map<String , List<Object[]>> map = new HashMap<>() ;
        for(Object[] o:datalist){
            String id =  o[0].toString() ;//单位唯一标识
            if(!map.containsKey(id)){
                map.put(id,new ArrayList<Object[]>());
            }
            map.get(id).add(o);
        }
        return  map ;
    }


    /**
     * 设置分支机构子节点指标
     * @return
     */
    private List<TMicroIdenmeta> setIdenmeta(){
        List<TMicroIdenmeta> li = new ArrayList<>();
        String sub_child = ConfigHelper.get("CHILDENTLIST");
        String [] child = sub_child.split(",");
        long l = 1;
        BigDecimal b = BigDecimal.valueOf(l);
        for(int i = 0;i<child.length;i++){
            TMicroIdenmeta iden = new TMicroIdenmeta();
            iden.setIdenCode(child[i]);
            iden.setIsfjg(b);
            iden.setIdenType(1);
            if("BRUNISCID".equals(child[i])){
                iden.setWjgName("UNISCID");
            }
            if("BRREGNO".equals(child[i])){
                iden.setWjgName("REGNO");
            }
            if("ENTNAME".equals(child[i])){
                iden.setWjgName("BRNAME");
            }
            if("LEREP".equals(child[i])){
                iden.setWjgName("PRIL");
            }
            if("PROLOC".equals(child[i])){
                iden.setWjgName("OPLOC");
            }

            if("ESTDATE".equals(child[i]) || "OPFROM".equals(child[i])
                    || "OPTO".equals(child[i]) || "APPRDATE".equals(child[i])){
                iden.setIdenType(3);
            }
            li.add(i,iden);
            System.out.println();
        }
        return li;
    }

    private final String sub_ls = "yzym_e_subls";


    //更新隶属关联基本信息临时表
    public boolean updateSUBLS(){
        //判断表是否存在
        String sql = "select count(*) from systables where tabname = ?";

        String ls = frDao.query(sql,sub_ls).get(0).toString();
        if(!"0".equals(ls)){
            delSUBLS();
        }else{
            createSUBLS();
        }

        insertSUBLS();

        System.out.println("隶属临时表 "+sub_ls+" 已更新 ！");
        return true;
    }

    //创建隶属关联基本信息临时表
    private boolean createSUBLS(){

        String sql = "create table yzym_e_subls(" +
                "        etpsid varchar(21) not null," +
                "        bruniscid varchar(18)," +
                "        uniscid varchar(18)," +
                "        regno varchar(20)," +
                "        entname varchar(200)," +
                "        s_ext_timestamp date," +
                "        enttype varchar(2)," +
                "        brregno varchar(15)," +
                "        brname varchar(200)," +
                "        estdate date," +
                "        lerep varchar(100)," +
                "        proloc varchar(200)," +
                "        opscope lvarchar(3000)," +
                "        opfrom date," +
                "        opto date," +
                "        regorg varchar(12)," +
                "        apprdate date" +
                ")";

        frDao.execute(sql);
        System.out.println("创建 "+sub_ls+" 成功");
       /* String index_sql = "create index index_subls on yzym_e_subls(etpsid)";
        frDao.execute(index_sql);
        System.out.println("创建 临时表 索引成功");*/
        return true;
    }


    //清空隶属关联基本信息临时表
    private boolean delSUBLS(){
        //判断表是否存在
        String sql = "delete from "+sub_ls;
        frDao.execute(sql);
        System.out.println("清空 "+sub_ls+" 成功 ");
        return true;
    }


    //插入隶属关联基本信息临时表数据
    private boolean insertSUBLS(){

        String sql = "insert into yzym_e_subls(ETPSID,BRUNISCID,UNISCID,REGNO,ENTNAME,S_EXT_TIMESTAMP," +
                "ENTTYPE,BRREGNO," +
                "BRNAME,ESTDATE,LEREP,PROLOC,OPSCOPE,OPFROM,OPTO,REGORG,APPRDATE)" +
                "select a.etpsid AS ETPSID,a.bruniscid AS BRUNISCID,a.uniscid AS UNISCID,a.regno " +
                "AS REGNO,a.ENTNAME AS ENTNAME," +
                "a.s_ext_timestamp AS S_EXT_TIMESTAMP,b.ENTTYPE AS ENTTYPE,b.regno AS BRREGNO," +
                "b.entname AS BRNAME,b.ESTDATE AS ESTDATE," +
                "b.LEREP AS LEREP,b.DOM AS PROLOC,b.OPSCOPE AS OPSCOPE,b.OPFROM AS OPFROM," +
                "b.OPTO AS OPTO,b.REGORG AS REGORG," +
                "b.APPRDATE AS APPRDATE from yzym_e_sub a,yzym_e_baseinfo b where b.etpsid = a.etpsid";

       // System.out.println(sql);
        frDao.execute(sql);
        System.out.println("关联基本信息表和分支机构表数据成功");
        return true;
    }


    /**
     * 添加文件柜导出任务
     * @param count
     * @param type
     * @return
     */
    private TUsertask  addTask(int count,String type){
        TUsertask t = new TUsertask() ;
        t.setTaskType(type);
        t.setStarttime(new Date());
        t.setCount(String.valueOf(count));
        t.setFinished(0); //未完成标识
        return  userTaskDao.save(t) ;
    };


    private TUsertask  updateTask(int completed,TUsertask task){
        task.setCompleted(String.valueOf(completed));
        return  userTaskDao.save(task) ;
    };


    public boolean addLog(String username,int record,Date starttime,Date endtime){

        TUserlogFrwjg log = new TUserlogFrwjg();

        log.setUsername(username);
        log.setUnitrecord(record);
        log.setStarttime(starttime);
        log.setEndtime(endtime);
        try {
            wjgDao.save(log);
        }catch (Exception e){
            System.out.println("保存文件柜日志异常");
        }
        return true;
    }
}
